package xin.marcher.module.rights.repository;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Repository;
import xin.marcher.module.common.core.PageResult;
import xin.marcher.module.rights.converter.*;
import xin.marcher.module.rights.domain.dto.*;
import xin.marcher.module.rights.domain.entity.*;
import xin.marcher.module.rights.domain.request.*;
import xin.marcher.module.rights.mapper.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 *
 */
@Repository
@Slf4j
public class RightsRepository {

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private PermissionConverter permissionConverter;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleConverter roleConverter;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserConverter userConverter;

    @Autowired
    private RolePermissionRelationMapper rolePermissionRelationMapper;

    @Autowired
    private RolePermissionRelationConverter rolePermissionRelationConverter;

    @Autowired
    private UserRoleRelationMapper userRoleRelationMapper;

    @Autowired
    private UserRoleRelationConverter userRoleRelationConverter;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     * 添加权限
     */
    public void savePermission(PermissionRequest request) {
        PermissionDO permissionDO = permissionConverter.convertDO(request);
        permissionDO.initCommon();
        permissionMapper.insert(permissionDO);
    }

    /**
     * 删除权限
     */
    public void removePermission(RemovePermissionRequest request) {
        permissionMapper.deleteById(request.getPermissionId());
    }

    /**
     * 查询权限列表
     */
    public List<PermissionDTO> queryPermission(QueryPermissionRequest request) {
        LambdaQueryWrapper<PermissionDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.isNull(Objects.isNull(request.getParentId()),
                PermissionDO::getParentId);
        queryWrapper.eq(Objects.nonNull(request.getParentId()),
                PermissionDO::getParentId, request.getParentId());
        queryWrapper.like(StringUtils.isNotBlank(request.getPermissionName()),
                PermissionDO::getPermissionName, request.getPermissionName());
        List<PermissionDO> permissionDOS = permissionMapper.selectList(queryWrapper);
        return permissionConverter.convertDTOs(permissionDOS);
    }

    /**
     * 添加角色
     */
    public Long saveRole(RoleRequest request) {
        RoleDO roleDO = roleConverter.convertDO(request);
        roleDO.initCommon();
        roleMapper.insert(roleDO);
        return roleDO.getId();
    }

    /**
     * 删除角色
     */
    public void removeRole(RemoveRoleRequest request) {
        roleMapper.deleteById(request.getRoleId());
    }

    /**
     * 查询角色列表
     */
    public PageResult<RoleDTO> queryRole(QueryRoleRequest request) {
        LambdaQueryWrapper<RoleDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StringUtils.isNotBlank(request.getRoleName()), RoleDO::getRoleName, request.getRoleName());
        Page<RoleDO> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<RoleDO> pageResult = roleMapper.selectPage(page, queryWrapper);
        return roleConverter.convertDTOs(pageResult);
    }

    /**
     * 添加用户
     */
    public Long saveUser(UserRequest request) {
        UserDO userDO = userConverter.convertDO(request);
        userDO.initCommon();
        log.info("request:{}", JSON.toJSONString(request));
        log.info("userDO:{}", JSON.toJSONString(userDO));
        userDO.setPassword(bCryptPasswordEncoder.encode(userDO.getPassword()));
        userMapper.insert(userDO);
        return userDO.getId();
    }

    public void saveUserRoleRelation(Long userId, UserRequest request) {
        if (Objects.isNull(userId) || CollectionUtils.isEmpty(request.getRoleIds())) {
            return;
        }

        List<UserRoleRelationDO> list = new ArrayList<>();
        List<Long> roleIds = request.getRoleIds();
        for (Long roleId : roleIds) {
            UserRoleRelationDO entity = new UserRoleRelationDO();
            entity.setUserId(userId);
            entity.setRoleId(roleId);
            entity.setUpdateUser(request.getOperateUser());
            entity.initCommon();
            list.add(entity);
        }
        userRoleRelationMapper.saveBatch(list);
    }

    /**
     * 删除用户
     */
    public void removeUser(RemoveUserRequest request) {
        userMapper.deleteById(request.getUserId());
    }

    /**
     * 查询用户列表
     */
    public PageResult<UserDTO> queryUser(QueryUserRequest request) {
        LambdaQueryWrapper<UserDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StringUtils.isNotBlank(request.getUsername()), UserDO::getUsername, request.getUsername());
        queryWrapper.eq(StringUtils.isNotBlank(request.getEmail()), UserDO::getEmail, request.getUsername());
        queryWrapper.eq(StringUtils.isNotBlank(request.getPhoneNumber()), UserDO::getPhoneNumber, request.getUsername());
        Page<UserDO> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<UserDO> pageResult = userMapper.selectPage(page, queryWrapper);
        return userConverter.convertDTOs(pageResult);
    }

    /**
     * 保存角色关联的权限
     */
    public void saveRolePermissionRelation(Long roleId, RoleRequest request) {
        if (Objects.isNull(roleId) || CollectionUtils.isEmpty(request.getPermissionIds())) {
            return;
        }

        List<RolePermissionRelationDO> list = new ArrayList<>();
        List<Long> permissionIds = request.getPermissionIds();
        for (Long permissionId : permissionIds) {
            RolePermissionRelationDO entity = new RolePermissionRelationDO();
            entity.setRoleId(roleId);
            entity.setPermissionId(permissionId);
            entity.setUpdateUser(request.getOperateUser());
            entity.initCommon();
            list.add(entity);
        }
        rolePermissionRelationMapper.saveBatch(list);
    }

    /**
     * 根据用户名查询用户记录
     */
    public UserDTO queryUserByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return null;
        }
        LambdaQueryWrapper<UserDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(UserDO::getUsername, username);
        UserDO userDO = userMapper.selectOne(queryWrapper);
        return userConverter.convertDTO(userDO);
    }

    /**
     * 根据用户id查询用户关联的角色
     */
    public List<UserRoleRelationDTO> queryUserRoleRelationByUserId(Long userId) {
        if (Objects.isNull(userId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<UserRoleRelationDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(UserRoleRelationDO::getUserId, userId);
        List<UserRoleRelationDO> userRoleRelationDOS = userRoleRelationMapper.selectList(queryWrapper);
        return userRoleRelationConverter.convertDTOS(userRoleRelationDOS);
    }

    /**
     * 根据角色编码查询角色
     */
    public RoleDTO queryRoleByRoleCode(String roleCode) {
        if (StringUtils.isBlank(roleCode)) {
            return null;
        }
        LambdaQueryWrapper<RoleDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(RoleDO::getRoleCode, roleCode);
        RoleDO roleDO = roleMapper.selectOne(queryWrapper);
        return roleConverter.convertDTO(roleDO);
    }

    /**
     * 根据权限编码查询权限
     */
    public PermissionDTO queryPermissionByPermissionCode(String permissionCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return null;
        }
        LambdaQueryWrapper<PermissionDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PermissionDO::getPermissionCode, permissionCode);
        PermissionDO permissionDO = permissionMapper.selectOne(queryWrapper);
        return permissionConverter.convertDTO(permissionDO);
    }

    /**
     * 根据角色id查询用户关联的角色
     */
    public List<UserRoleRelationDTO> queryUserRoleRelationByRoleId(Long roleId) {
        if (Objects.isNull(roleId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<UserRoleRelationDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(UserRoleRelationDO::getRoleId, roleId);
        List<UserRoleRelationDO> userRoleRelationDOS = userRoleRelationMapper.selectList(queryWrapper);
        return userRoleRelationConverter.convertDTOS(userRoleRelationDOS);
    }

    /**
     * 根据权限id查询角色和权限之间的关联关系
     */
    public List<RolePermissionRelationDTO> queryRolePermissionRelationByPermissionId(Long permissionId) {
        if (Objects.isNull(permissionId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<RolePermissionRelationDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(RolePermissionRelationDO::getPermissionId, permissionId);
        List<RolePermissionRelationDO> rolePermissionRelationDOS = rolePermissionRelationMapper.selectList(queryWrapper);
        return rolePermissionRelationConverter.convertDTOS(rolePermissionRelationDOS);
    }

    /**
     * 根据角色id查询角色关联的权限
     */
    public List<RolePermissionRelationDTO> queryRolePermissionRelation(List<Long> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<RolePermissionRelationDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(RolePermissionRelationDO::getRoleId, roleIds);
        List<RolePermissionRelationDO> rolePermissionRelationDOS = rolePermissionRelationMapper.selectList(queryWrapper);
        return rolePermissionRelationConverter.convertDTOS(rolePermissionRelationDOS);
    }

    /**
     * 根据id批量查询权限记录
     */
    public List<PermissionDTO> queryPermissionByIds(List<Long> permissionIds) {
        if (Objects.isNull(permissionIds)) {
            return Collections.emptyList();
        }

        List<PermissionDO> permissionDOS = permissionMapper.selectBatchIds(permissionIds);
        return permissionConverter.convertDTOs(permissionDOS);
    }

    /**
     * 根据id查询用户
     */
    public UserDTO queryUserById(Long userId) {
        if (Objects.isNull(userId)) {
            return null;
        }
        UserDO userDO = userMapper.selectById(userId);
        if (Objects.isNull(userDO)) {
            return null;
        }
        return userConverter.convertDTO(userDO);
    }

    /**
     * 修改用户的password
     */
    public boolean modifyPassword(Long userId, String encodedPassword) {
        UserDO entity = new UserDO();
        entity.setId(userId);
        entity.setPassword(encodedPassword);
        return userMapper.updateById(entity) == 1;
    }

    /**
     * 删除用户和角色的关联关系
     */
    public void removeUserRoleRelationByUserId(Long userId) {
        if (Objects.isNull(userId)) {
            return;
        }
        LambdaQueryWrapper<UserRoleRelationDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(UserRoleRelationDO::getUserId, userId);
        userRoleRelationMapper.delete(queryWrapper);
    }

    /**
     * 删除角色和权限的关联关系
     */
    public void removeRolePermissionRelationByRoleId(Long roleId) {
        if (Objects.isNull(roleId)) {
            return;
        }
        LambdaQueryWrapper<RolePermissionRelationDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(RolePermissionRelationDO::getRoleId, roleId);
        rolePermissionRelationMapper.delete(queryWrapper);
    }

    /**
     * 根据权限id查询该权限下的子权限
     */
    public List<PermissionDTO> queryPermissionByParentId(Long permissionId) {
        if (Objects.isNull(permissionId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<PermissionDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PermissionDO::getParentId, permissionId);
        List<PermissionDO> permissionDOS = permissionMapper.selectList(queryWrapper);
        return permissionConverter.convertDTOs(permissionDOS);
    }
}
